#include "TListaSimple.h"

void LS_Crear(TListaSimple* lista, int tam_dato) {
	lista->corriente = NULL;
	lista->primero = NULL;
	lista->tam_dato = tam_dato;
	#ifdef __DEBUG__
	printf("LS_Crear: Entra.\n");
	#endif
}

void LS_Vaciar(TListaSimple* lista) {
	TNodoSimple *nodo, *siguiente;

	for (nodo = lista->primero; nodo; nodo = siguiente) {
		  siguiente = nodo->siguiente;
		  free(nodo->elemento);
		  free(nodo);
	}

	lista->primero = lista->corriente = NULL;
}

int LS_Vacia(TListaSimple lista) {
       return (lista.primero == NULL);
}

void LS_ElemCorriente(TListaSimple lista, void* elemento) {
       memcpy(elemento, lista.corriente->elemento, lista.tam_dato);
}

void LS_ModifCorriente(TListaSimple* lista, void* elemento) {
       memcpy(lista->corriente->elemento, elemento, lista->tam_dato);
}

int LS_MoverCorriente(TListaSimple* lista, TMovimiento movimiento) {
	if (LS_Vacia(*lista)) {
		return TLS_ERR_LISTAVACIA;
	}
    else {
		switch (movimiento) {
			case LS_PRIMERO:
				lista->corriente = lista->primero;
				break;

			case LS_SIGUIENTE:
				if (lista->corriente->siguiente == NULL) {
					return TLS_ERR_NOHAYSIGUIENTE;
				}
				else {
					lista->corriente = lista->corriente->siguiente;
				}
				break;

			case LS_ANTERIOR:
				return TLS_ERR_NOIMPLEMENTADO;
		}

    	return TLS_OK;
    }
}

int LS_BorrarCorriente(TListaSimple* lista) {
	TNodoSimple* nodo;

	nodo = lista->corriente;

	if (LS_Vacia(*lista)) {
		return TLS_ERR_LISTAVACIA;
	}

	if (lista->corriente == lista->primero) {
		lista->primero = lista->corriente->siguiente;
		lista->corriente = lista->primero;
    }
    else {
		TNodoSimple* nodo_aux = lista->primero;

		while (nodo_aux->siguiente != lista->corriente) {
			nodo_aux = nodo_aux->siguiente;
		}

		nodo_aux->siguiente = lista->corriente->siguiente;
		if (nodo_aux->siguiente) {
			lista->corriente = nodo_aux->siguiente;
        }
		else {
			lista->corriente = nodo_aux;
		}
	}

    free(nodo->elemento);
    free(nodo);

    return TLS_OK;
}

/* TODO: que pueda insertar en el nodo anterior */
int LS_Insertar(TListaSimple* lista, TMovimiento movimiento, void* elemento) {
	TNodoSimple* nodo = (TNodoSimple*) malloc(sizeof(TNodoSimple));

    if (!nodo)
		return TLS_ERR_MEMORIA;

    if ((LS_Vacia(*lista)) || (movimiento == LS_PRIMERO) /*|| ((movimiento == LS_ANTERIOR) && (lista->primero == lista->corriente))*/) {
		nodo->siguiente = NULL;
		lista->primero = nodo;
		#ifdef __DEBUG__
        printf("LS_Insertar:\n Inserto en primero\n");
        #endif
	}
	else {
		if (movimiento == LS_SIGUIENTE) {
			nodo->siguiente = lista->corriente->siguiente;
			lista->corriente->siguiente = nodo;
		}
		else {
			if (movimiento==LS_ANTERIOR){
			TNodoSimple* nodo_aux = lista->primero;
			while (nodo_aux->siguiente != lista->corriente) {
				nodo_aux = nodo_aux->siguiente;
			}
            nodo_aux->siguiente = nodo;
			nodo->siguiente = lista->corriente;
			}
		}
	}

    nodo->elemento = malloc(lista->tam_dato);
	memcpy(nodo->elemento, elemento, lista->tam_dato);
	lista->corriente = nodo;

	return TLS_OK;
}
